package network;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @version 1.8
 * @Author Djx_hmbb
 * @Date 2023/10/9 14:04
 * @注释:Tcp回显服务器
 */
public class TcpEchoServer {
    private ServerSocket serverSocket = null;

    public TcpEchoServer(int port ) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    //修改前
  /*  public void start() throws IOException {
        System.out.println("启动服务器！");
        while (true){
            //使用clientSocket和具体客户交流（就像售楼小哥带你去找售楼小姐一样，分工不同）
            Socket clientSocket = serverSocket.accept();
            processConnection(clientSocket);
        }
    }*/

    //修改后
    public void start() throws IOException {
        System.out.println("启动服务器！");
        //此处使用CachedThreadPool，使用 FixedThreadPool不太合适（线程数不太应该是有固定的....)
        ExecutorService threadPool = Executors.newCachedThreadPool();
        while (true){
            //使用clientSocket和具体客户交流（就像售楼小哥带你去找售楼小姐一样，分工不同）
            Socket clientSocket = serverSocket.accept();
//            Thread t = new Thread(()->{
//                try {
//                    processConnection(clientSocket);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            });
//            t.start();

            //使用线程池
            threadPool.submit(()->{
                try {
                    processConnection(clientSocket);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
    private void processConnection(Socket clientSocket) throws IOException {
        System.out.printf("[%s:%d] 客户端上线！\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
//        基于上述socket对象和客户端通信
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()){
            //由于需要处理多个请求和响应，所以用while
            while (true){
                //1.读请求
                Scanner s = new Scanner(inputStream);
                if(!s.hasNext()){
                    //如果不存在下一条请求，则结束，客户端关闭
                    System.out.printf("[%s：%d] 客户端关闭！\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
                    break;
                }
                //注意！！！这里是碰到 换行符、空格、其他换行符 就停止，是不包含上述空白符的
                String request = s.next();
                //2.根据请求构造响应
                String response = process(request);
                //3.返回响应结果
                //outputStream 没有write String 这样的功能，可以吧String里的字节数组拿出来，进行写入、
                //也可以用字符流转换一下
                PrintWriter printWriter = new PrintWriter(outputStream);
                //此处用 println（换行），方便对端接受并解析
                printWriter.println(response);
                //flush用来刷新缓存，保证当前写入的数据全部发出
                printWriter.flush();
                System.out.printf("[%s:%d] req:%s  res:%s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),request,response);
            }
        }catch(IOException e){
            e.printStackTrace();
        }finally {
            clientSocket.close();
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer tcpEchoServer = new TcpEchoServer(9090);
        tcpEchoServer.start();
    }
}
